<template>
  <div style="margin-top: 20px">
    <ko-card :title="$t('business.network.rule')">
      <el-form ref="form" label-position="top" :model="editForm">
        <el-card
          v-for="(rule, ind) in editForm.rules"
          v-bind:key="ind"
          style="
            background-color: #292a2e;
            margin-top: 10px;
            position: relative;
          "
        >
          <div
            style="float: right; padding: 3px 0; position: relative; z-index: 1"
          >
            <el-button
              v-if="editForm.rules.length > 1"
              type="text"
              @click="onRemoveRule(ind)"
              >{{ $t("commons.button.delete") }}
            </el-button>
          </div>
          <div>
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item :label="$t('business.network.host')" prop="host">
                  <el-input
                    v-model="rule.host"
                    placeholder="e.g. example.com"
                  />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="20">
              <el-col :span="24">
                <table style="width: 100%; padding: 0" class="tab-table">
                  <tr>
                    <th scope="col" width="10%" align="left">
                      <label>{{ $t("business.network.path") }}</label>
                    </th>
                    <th scope="col" width="38.5%" align="left" />
                    <th scope="col" width="20%" align="left">
                      <label>{{ $t("business.network.target") }} Service</label>
                    </th>
                    <th scope="col" width="10%" align="left">
                      <label>{{ $t("business.network.port") }}</label>
                    </th>
                    <th />
                  </tr>
                  <tr
                    v-for="(row, index) in rule.http.paths"
                    v-bind:key="index"
                  >
                    <td>
                      <el-select v-model="row.pathType">
                        <el-option label="Prefix" value="Prefix" />
                        <el-option label="Exact" value="Exact" />
                        <el-option
                          label="ImplementationSpecific"
                          value="ImplementationSpecific"
                        />
                      </el-select>
                    </td>
                    <td>
                      <el-input v-model="row.path" @change="syncToRulesArray" />
                    </td>
                    <td v-if="row.backend.serviceName !== undefined">
                      <el-select
                        v-model="row.backend.serviceName"
                        style="width: 100%"
                        @change="
                          onServiceChange(row.backend.serviceName, index)
                        "
                      >
                        <el-option
                          v-for="service in services"
                          :key="service.metadata.name"
                          :label="service.metadata.name"
                          :value="service.metadata.name"
                        />
                      </el-select>
                    </td>
                    <td v-else>
                      <el-select
                        v-model="row.backend.service.name"
                        style="width: 100%"
                        @change="
                          onServiceChange(row.backend.service.name, index)
                        "
                      >
                        <el-option
                          v-for="service in services"
                          :key="service.metadata.name"
                          :label="service.metadata.name"
                          :value="service.metadata.name"
                        />
                      </el-select>
                    </td>

                    <td v-if="row.backend.servicePort !== undefined">
                      <el-select v-model="row.backend.servicePort">
                        <el-option
                          v-for="port in servicePorts[index]"
                          :key="port.name"
                          :label="port.port"
                          :value="port.port"
                        />
                      </el-select>
                    </td>
                    <td v-else>
                      <el-select v-model="row.backend.service.port.number">
                        <el-option
                          v-for="port in servicePorts[index]"
                          :key="port.name"
                          :label="port.port"
                          :value="port.port"
                        />
                      </el-select>
                    </td>
                    <td>
                      <el-button
                        type="text"
                        style="font-size: 10px"
                        @click="onDeletePath(ind, index)"
                      >
                        {{ $t("commons.button.delete") }}
                      </el-button>
                    </td>
                  </tr>
                  <tr>
                    <td align="left">
                      <el-button @click="onAddPath(rule)">
                        {{ $t("commons.button.add")
                        }}{{ $t("business.network.path") }}
                      </el-button>
                    </td>
                  </tr>
                </table>
              </el-col>
            </el-row>
          </div>
        </el-card>
      </el-form>
      <el-button style="margin-top: 10px" @click="onAddRule">
        {{ $t("commons.button.add") }}{{ $t("business.network.rule") }}
      </el-button>
    </ko-card>
  </div>
</template>

<script setup lang="ts">
import KoCard from "@/views/domain/kubeHud/views/components/ko-card/index.vue";
import { computed, onMounted, ref, watch } from "vue";
import { setObjectFromKey } from "../../../utils";
import { useK8SApi } from "../../../api/k8s";

const { serviceRepo } = useK8SApi();

type Prop = {
  rulesArray?: any[];
  namespace?: string;
  cluster?: string;
  mode?: string;
  newVersion?: boolean;
};

const emit = defineEmits(["update:rulesArray"]);
const props = withDefaults(defineProps<Prop>(), {
  rulesArray: () => [],
  newVersion: false
});

const editForm = ref({
  rules: []
});

const services = ref([]);
const servicePorts = ref({});

const servicePath = computed(() => {
  const nestedPath = "service.name";
  const flatPath = "serviceName";
  return props.newVersion ? nestedPath : flatPath;
});

const portPath = computed(() => {
  const nestedPath = "service.port.number";
  const flatPath = "servicePort";
  return props.newVersion ? nestedPath : flatPath;
});

const onRemoveRule = (index: number) => {
  editForm.value.rules.splice(index, 1);
};

const syncToRulesArray = () => {
  emit("update:rulesArray", editForm.value.rules);
};

const onServiceChange = (svrName: string, index: number) => {
  const current = services.value.find(item => item.metadata.name === svrName);
  if (current) {
    servicePorts.value[index] = current.spec.ports;
  }
};

const getDefaultRule = () => {
  const rule = {
    host: "",
    http: {
      paths: [
        {
          backend: {},
          path: "",
          pathType: ""
        }
      ]
    }
  };

  setObjectFromKey(rule.http.paths[0].backend, servicePath.value, "");
  setObjectFromKey(rule.http.paths[0].backend, portPath.value, 0);

  return rule;
};

const onAddRule = () => {
  editForm.value.rules.push(getDefaultRule());
};

const onAddPath = (row: any) => {
  const path = {
    backend: {},
    path: "",
    pathType: ""
  };

  setObjectFromKey(path.backend, servicePath.value, "");
  setObjectFromKey(path.backend, portPath.value, 0);

  row.http.paths.push(path);
};

const onDeletePath = (ruleIndex: number, pathIndex: number) => {
  editForm.value.rules[ruleIndex].http.paths.splice(pathIndex, 1);
};

const getServices = async () => {
  const { items } = await serviceRepo.getService({
    clusterName: props.cluster,
    namespace: props.namespace
  });

  services.value = items;
};

watch(
  () => props.namespace,
  (nv, ov) => {
    if (nv !== ov) {
      for (let i = 0; i < editForm.value.rules.length; i++) {
        for (let j = 0; j < editForm.value.rules[i].http.paths.length; j++) {
          setObjectFromKey(
            editForm.value.rules[i].http.paths[j].backend,
            servicePath.value,
            ""
          );
          setObjectFromKey(
            editForm.value.rules[i].http.paths[j].backend,
            portPath.value,
            0
          );
        }
      }
    }
  }
);

onMounted(() => {
  if (props.rulesArray) {
    editForm.value.rules = props.rulesArray;
  } else {
    editForm.value.rules = [getDefaultRule()];
  }

  syncToRulesArray();
  getServices();
});
</script>

<style scoped></style>
